from ocr.paddle.image import getImageInfo
from ocr.cert.config import sfzs, yyzzs, qy_types, jzzs, jlsfz_x, jlsfz_y, hkbs, hzs
from ocr.cert.validator import sex_verify
from datetime import datetime
import re

class Card:
    def get_index(self, opts, key):
        for i, item in enumerate(opts):
            if re.match(rf'^{key}', item[1][0]) is not None:
                return i

    def get_value(self, opts, index):
        rows = list()
        for i, item in enumerate(opts):
            position = item[0]
            start = position[0]
            end = position[len(position) - 1]
            if start[1] < index and end[1] > index:
                rows.append({
                    'x1': start[0],
                    'x2': position[1][0],
                    'y1': start[1],
                    'y2': end[1],
                    'label': item[1][0]
                })
        rows = sorted(rows, key=lambda k: k['x1'])
        return rows

    def get_value_x(self, opts, index, position):
        rows = list()
        for i, item in enumerate(opts[position:]):
            position = item[0]
            start = position[0]
            end = position[1]
            if start[0] < index and end[0] > index:
                rows.append({
                    'x1': start[0],
                    'x2': position[1][0],
                    'y1': start[1],
                    'y2': end[1],
                    'label': item[1][0]
                })
        rows = sorted(rows, key=lambda k: k['x1'])
        return rows

    def get_label(self, opts, index, key):
        label = None
        for i, item in enumerate(opts):
            position = item[0]
            start = position[0]
            end = position[len(position) - 1][1]
            if start[1] < index and end > index:
                if len(key) > 1 and key['x1'] <= position[0][0] and key['x2'] >= position[1][0]:
                    label = item[1][0]
                elif key['x1'] <= position[0][0] and len(key) < 2:
                    label = item[1][0]
        return label

    def get_card(self, config, keys):
        maps = dict()
        configs = list()
        for key in keys:
            position = self.get_index(config, key)
            if position is not None:
                item = config[position]
                pos = item[0]
                start = pos[0][1]
                end = pos[len(pos) - 1][1]
                middle = (start + end) / 2
                rows = self.get_value(config, middle)
                configs.append(rows)
        for index, row in enumerate(configs):
            labs = list()
            for key in row:
                if re.search(r'住址', key['label']) is not None:
                    position = self.get_index(config,key['label'])
                    key_next = row[-1]
                    middle = key['y2'] * 2 - key['y1']
                    middle_x = (key_next['x2'] + key_next['x1']) / 2
                    rows = self.get_value(config, middle)
                    rows = self.get_value_x(config, middle_x, position)
                    addr = {'label': '住址'}
                    labs.append(key['label'].replace('住址', ''))
                    for col in rows:
                        labs.append(col['label'])
                    addr.setdefault('value', ''.join(labs))
                    maps.setdefault('address', addr)
                else:
                    labs.append(key['label'])
            label = ''.join(labs)
            if re.search(r'公民身份', label) is not None:
                maps.setdefault('code', {
                    'label': '公民身份号码',
                    'value': re.sub(r'[\u4e00-\u9fa5]', '', label)
                })
            elif re.search(r'性别', label) is not None:
                label = label.replace('性别', '')
                if re.search(r'民族', label) is not None:
                    labs = label.split('民族')
                    maps.setdefault('sex', {
                        'label': '性别',
                        'value': labs[0]
                    })
                    maps.setdefault('nation', {
                        'label': '民族',
                        'value': labs[1]
                    })
                else:
                    maps.setdefault('sex', {
                        'label': '性别',
                        'value': label
                    })
            elif re.search(r'出生', label) is not None:
                maps.setdefault('birth', {
                    'label': '出生',
                    'value': label.replace('出生', '')
                })
            elif re.search(r'住址', label) is not None:
                print(label)
                maps.setdefault('address', {
                    'label': '住址',
                    'value': label.replace('住址', '')
                })
            elif re.search(r'签发机关', label) is not None:
                maps.setdefault('organ', {
                    'label': '签发机关',
                    'value': label.replace('签发机关', '')
                })
            elif re.search(r'有效期限', label) is not None:
                maps.setdefault('dataRange', {
                    'label': '有效期限',
                    'value': label.replace('有效期限', '')
                })
            elif re.search(r'姓名', label) is not None:
                maps.setdefault('name', {
                    'label': '姓名',
                    'value': label.replace('姓名', '')
                })
            elif re.search(r'通行证', label) is not None:
                maps.setdefault('address', {
                    'label': '通行证号码',
                    'value': re.sub(r'[\u4e00-\u9fa5]', '', label)
                })
        return maps

    '''
    居民身份证
    status 0正常 1文件上传失败 2数据异常 3人工补充数据
    lists paddle解析返回数据
    '''

    def get_sfz(self, path: str):
        opts = getImageInfo(path)
        config = opts.copy()
        keys = sfzs.keys()
        lists = self.get_card(config, keys)
        code = lists.get("code")
        value = code.get('value')
        res = {
            "status": 3,
            "lists": {}
        }
        if len(value) == 18:
            birth = lists.get('birth')
            date = datetime.strptime(birth.get('value'), '%Y年%m月%d日')
            nowDate = date.strftime('%Y%m%d')
            sex = lists.get('sex')
            if re.search(nowDate, value) is not None and sex_verify(value[16], sex.get('value')):
                res = {
                    "status": 0,
                    "lists": lists
                }
        return res

    '''
    营业执照
    status 0正常 1文件上传失败 2数据异常 3人工补充数据
    lists paddle解析返回数据
    '''

    def get_yyzz(self, path: str):
        opts = getImageInfo(path)
        config = opts.copy()
        keys = yyzzs.keys()
        maps = dict()
        configs = list()
        for key in keys:
            position = self.get_index(config, key)
            if position is not None:
                item = config[position]
                pos = item[0]
                start = pos[0][1]
                end = pos[len(pos) - 1][1]
                middle = (start + end) / 2
                rows = self.get_value(config, middle)
                configs.append(rows)
        for val in configs:
            labs = list()
            for keys in val:
                if keys['label'] == '统一社会信用代码':
                    code_s = {'label': '统一社会信用代码'}
                    codes = [keys['y2'] - keys['y1'], (keys['y2'] - keys['y1']) / 2, (keys['y2'] - keys['y1']) / 2]
                    for code in codes:
                        middle = keys['y2'] + code
                        rows = self.get_value(config, middle)
                        status = False
                        for row in rows:
                            if re.search(r'[0-9A-Z]', row['label']) is not None:
                                code_s.setdefault('value', row['label'])
                                maps.setdefault('code', code_s)
                                status = True
                                break
                        if status:
                            break
                else:
                    labs.append(keys['label'])
            label = ''.join(labs)
            if re.search(r'名称', label) is not None:
                label = label.replace('名称', '')
                if re.search(r'注册资本', label) is not None:
                    labs = label.split('注册资本')
                    maps.setdefault('name', {
                        'label': '名称',
                        'value': labs[0]
                    })
                    maps.setdefault('zc_zb', {
                        'label': '注册资本',
                        'value': labs[1]
                    })
                else:
                    maps.setdefault('name', {
                        'label': '名称',
                        'value': label
                    })
            elif re.search(r'类型', label) is not None:
                label = label.replace('类型', '')
                if re.search(r'注册资本', label) is not None:
                    labs = label.split('成立日期')
                    types = {
                        'label': '类型',
                        'value': labs[0]
                    }
                    for col in qy_types:
                        if re.sub(r'[（）()]', '', qy_types[col]) == re.sub(r'[（）()]', '', labs[0]):
                            types.setdefault('code', col)
                            break
                    maps.setdefault('type', types)
                    maps.setdefault('create_time', {
                        'label': '成立日期',
                        'value': labs[1]
                    })
                else:
                    maps.setdefault('type', {
                        'label': '类型',
                        'value': label
                    })
            elif re.search(r'法定代表人', label) is not None:
                label = label.replace('法定代表人', '')
                if re.search(r'住所', label) is not None:
                    labs = label.split('住所')
                    maps.setdefault('fr', {
                        'label': '法定代表人',
                        'value': labs[0]
                    })
                    maps.setdefault('address', {
                        'label': '住所',
                        'value': labs[1]
                    })
                else:
                    maps.setdefault('fr', {
                        'label': '法定代表人',
                        'value': label
                    })
        return {
            'status': 3,
            'lists': maps
        }

    # 居民户口薄
    def get_hkb(self, path: str):
        opts = getImageInfo(path)
        config = opts.copy()
        maps = dict()
        configs = list()
        keys = hkbs.keys()
        for key in keys:
            position = self.get_index(config, key)
            if position is not None:
                item = config[position]
                pos = item[0]
                start = pos[0][1]
                end = pos[len(pos) - 1][1]
                middle = (start + end) / 2
                rows = self.get_value(config, middle)
                configs.append(rows)
        return maps

    # 港澳台居民居住证
    def get_jzz(self, path: str):
        opts = getImageInfo(path)
        config = opts.copy()
        keys = jzzs.keys()
        return self.get_card(config, keys)

    # 外国人永久居留身份证
    def get_jlsfz(self, path: str):
        opts = getImageInfo(path)
        config = opts.copy()
        key_x = jlsfz_x.keys()
        key_y = jlsfz_y.keys()
        maps = dict()
        configs = list()
        for key in key_x:
            position = self.get_index(config, key)
            if position is not None:
                item = config[position]
                pos = item[0]
                start = pos[0][1]
                end = pos[len(pos) - 1][1]
                middle = (start + end) / 2
                rows = self.get_value(config, middle)
                configs.append(rows)
        for key in configs:
            for i, val in enumerate(key):
                pos = {
                    'x1': val['x1'] - 15
                }
                if i < len(key) - 1:
                    pos['x2'] = key[i + 1]['x1']
                middles = [val['y2'] * 2 - val['y1'], val['y2'] * 2 - val['y1'] + (val['y2'] - val['y1']) / 2]
                for middle in middles:
                    label = self.get_label(config, middle, pos)
                    if label is not None:
                        if re.search(r'姓名', val['label']) is not None:
                            maps['name'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'性别', val['label']) is not None:
                            maps['sex'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'出生', val['label']) is not None:
                            maps['birth'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'国籍', val['label']) is not None:
                            maps['country'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'有效期限', val['label']) is not None:
                            maps['dataRange'] = {
                                'label': val['label'],
                                'value': label
                            }
                        break
        for key in key_y:
            position = self.get_index(config, key)
            if position is not None:
                item = config[position]
                pos = item[0]
                start = pos[0][1]
                end = pos[len(pos) - 1][1]
                middle = (start + end) / 2
                rows = self.get_value(config, middle)
                if len(rows) > 1:
                    maps['code'] = {
                        'label': '证件号码/ID No',
                        'value': rows[1]['label']
                    }
        return maps

    # 护照
    def get_hz(self, path: str):
        opts = getImageInfo(path)
        config = opts.copy()
        key_x = hzs.keys()
        maps = dict()
        configs = list()
        for key in key_x:
            position = self.get_index(config, key)
            if position is not None:
                item = config[position]
                pos = item[0]
                start = pos[0][1]
                end = pos[len(pos) - 1][1]
                middle = (start + end) / 2
                rows = self.get_value(config, middle)
                configs.append(rows)
        for key in configs:
            for i, val in enumerate(key):
                pos = {
                    'x1': val['x1'] - 15
                }
                if i < len(key) - 1:
                    pos['x2'] = key[i + 1]['x1']
                middles = [val['y2'] * 2 - val['y1'], val['y2'] * 2 - val['y1'] + (val['y2'] - val['y1']) / 2]
                for middle in middles:
                    label = self.get_label(config, middle, pos)
                    if label is not None:
                        if re.search(r'护照', val['label']) is not None:
                            maps['p_no'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'性别', val['label']) is not None:
                            maps['sex'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'出生日期', val['label']) is not None:
                            maps['cs_rq'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'国家', val['label']) is not None:
                            maps['country'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'^姓', val['label']) is not None:
                            maps['x'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'^名', val['label']) is not None:
                            maps['m'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'出生地点', val['label']) is not None:
                            maps['cs_dd'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'签发地点', val['label']) is not None:
                            maps['qf_dd'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'签发日期', val['label']) is not None:
                            maps['qf_rq'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'有效期', val['label']) is not None:
                            maps['dataRange'] = {
                                'label': val['label'],
                                'value': label
                            }
                        elif re.search(r'签发机关', val['label']) is not None:
                            maps['organ'] = {
                                'label': val['label'],
                                'value': label
                            }
                        break
        return maps


initCard = Card()
